﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Weazel.Willows.Model
{
	public class CompoundType : BasicType
	{
		private List<BasicType> types;
		public List<BasicType> Types
		{
			get { return types; }
		}

		public CompoundType(TypeRegistry registry, List<BasicType> types, string name)
			: base(registry, name)
		{
			this.types = types;
		}

		public CompoundType(TypeRegistry registry)
			: base(registry, null)
		{
			this.types = new List<BasicType>();
		}

		public override void Resolve()
		{
			System.Diagnostics.Debug.Assert(!Resolved);
			foreach (BasicType type in types)
				type.Resolve();

			Resolved = true;
		}

		public override int BitWidth
		{
			get 
			{
				int w = 0;
				foreach (BasicType type in types)
					w += type.BitWidth;

				return w;
			}
		}

		public override bool IsSimpleType
		{
			get { return false; }
		}

		public void Read(XmlElement description)
		{
			System.Diagnostics.Debug.Assert(description.Name == "TypeDef");
			System.Diagnostics.Debug.Assert(description.HasChildNodes);
			System.Diagnostics.Debug.Assert(description.HasAttribute("Name"));

			this.Name = description.Attributes["Name"].Value;

			foreach (XmlNode node in description.GetElementsByTagName("TypeDef"))
			{
				XmlElement element = node as XmlElement;

				if (element.HasAttribute("width"))
				{
					Type type = new Type(Registry);
					type.Read(element);
					types.Add(type);
				}
				else
				{
					AliasType alias = new AliasType(Registry);
					alias.Read(element);
					types.Add(alias);
				}
			}
		}

		public override string ToString()
		{
			StringBuilder str = new StringBuilder();
			str.Append("\n");
			foreach (BasicType type in types)
				str.Append("\t" + type.ToString() + "\n");

			return str.ToString();
		}
	}
}
